package com.flmz.system.service.sysuser.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.flmz.common.core.constants.HttpConstants;
import com.flmz.common.core.domain.LoginUser;
import com.flmz.common.core.domain.R;
import com.flmz.common.core.domain.vo.LoginUserVO;
import com.flmz.common.core.enums.ResultCode;
import com.flmz.common.core.enums.UserIdentity;
import com.flmz.common.security.exception.ServiceException;
import com.flmz.common.security.service.TokenService;
import com.flmz.system.domain.sysuser.SysUser;
import com.flmz.system.domain.sysuser.dto.SysUserSaveDTO;
import com.flmz.system.mapper.sysuser.SysUserMapper;
import com.flmz.system.service.sysuser.ISysUserService;
import com.flmz.system.utils.BCryptUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RefreshScope // 支持配置动态刷新，可以解决在运行时动态更新配置文件内容的场景（jwt的secret）
public class SysUserServiceImpl implements ISysUserService {

	@Autowired
	private SysUserMapper sysUserMapper;

	@Autowired
	private TokenService tokenService;

	// 把jwt的签名放在nacos上进行配置，可以定期更换
	@Value("${jwt.secret}")
	private String secret;

	@Override
	public R<String> login(String userAccount, String password) {

		// 通过账号在数据库中查询，对应的用户信息
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();

		// select password from tb_sys_user where user_account = #{userAccount}
		SysUser sysUser = sysUserMapper.selectOne(queryWrapper
				.select(SysUser::getUserId, SysUser::getPassword, SysUser::getNickName)
				.eq(SysUser::getUserAccount, userAccount));

//		R loginResult = new R();
		// 查询为空，返回信息 “当前用户不存在”
		if (sysUser == null) {
//			loginResult.setCode(ResultCode.FAILED_USER_NOT_EXISTS.getCode());
//			loginResult.setMsg(ResultCode.FAILED_USER_NOT_EXISTS.getMsg());
			return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
		}

		// 使用BCrypt来进行密码匹配，登录成功，直接跳转
		if (BCryptUtils.matchesPassword(password, sysUser.getPassword())) {
//			loginResult.setCode(ResultCode.SUCCESS.getCode());
//			loginResult.setMsg(ResultCode.SUCCESS.getMsg());
			String token = tokenService.createToken(sysUser.getUserId(),
					secret, UserIdentity.ADMIN.getValue(), sysUser.getNickName(), null);
			return R.ok(token);
		}

		// 密码不匹配，返回信息 “账号或密码错误”
//		loginResult.setCode(ResultCode.FAILED_LOGIN.getCode());
//		loginResult.setMsg(ResultCode.FAILED_LOGIN.getMsg());
		return R.fail(ResultCode.FAILED_LOGIN);
	}

	@Override
	public boolean logout(String token) {
		if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
			token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
		}
		return tokenService.deleteLoginUser(token, secret);
	}

	@Override
	public R<LoginUserVO> info(String token) {
		if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
			token = token.replaceFirst(HttpConstants.PREFIX, "");
		}
		LoginUser loginUser = tokenService.getLoginUser(token, secret);
		if (loginUser == null) {
			return R.fail();
		}
		LoginUserVO loginUserVO = new LoginUserVO();
		loginUserVO.setNickName(loginUser.getNickName());
		return R.ok(loginUserVO);
	}

	@Override
	public int add(SysUserSaveDTO sysUserSaveDTO) {
		// 判断用户是否存在
		List<SysUser> sysUserList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
				.eq(SysUser::getUserAccount, sysUserSaveDTO.getUserAccount()));
		if (CollectionUtil.isNotEmpty(sysUserList)) {
			// 用户已经存在  自定义的异常，公共的异常类
			throw new ServiceException(ResultCode.AILED_USER_EXISTS);
		}
		// 将DTO转成实体
		SysUser sysUser = new SysUser();
		sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
		sysUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));

		return sysUserMapper.insert(sysUser);
	}
}
